package com.zee.demo;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.google.gson.Gson;
import com.unity3d.player.UnityPlayer;
import com.zee.demo.utils.CommonUtil;
import com.zee.digital.human.AvatarSDK;
import com.zee.digital.human.IBroadcastCallbacks;
import com.zee.digital.human.IEngineLifecycleEvents;
import com.zee.digital.human.data.model.AvatarCameraType;
import com.zee.digital.human.data.model.InitConfig;
import com.zee.digital.human.data.model.SDKResponse;
import com.zee.digital.human.exception.SDKException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class DemoActivity extends AppCompatActivity {

    private static final String TAG = "AvatarSDK";
    protected UnityPlayer mUnityPlayer;
    private AvatarSDK avatarSDK;
    private FrameLayout rootFrameLayout;
    private boolean isEngineReady = false;
    private boolean isDigitalHumanReady = false;
    private String currentAvatarCode;

    private final List<String> dhItems =  new ArrayList<>(Arrays.asList("DH_HUMAN_MODEL003_000018", "DH_HUMAN_MODEL003_000015", "DH_HUMAN_MODEL103_000017"));
    private final List<String> actionItems =  new ArrayList<>(Arrays.asList("DH_ACTION_MODEL003_000026", "DH_ACTION_MODEL003_000031", "DH_ACTION_MODEL103_000036"));
    private String token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbklkIjoiNTM2NjM3NDUxMDcxMjQyMjQ2IiwidXNlcklkIjo1MDI4NDI5Mjc3Nzc5NTE3NTEsInVzZXJDb2RlIjoienduXzUwMjg0MjkyNzc3Nzk1MTc1MiIsImV4cGlyZVRpbWUiOiIyMDI2LTAxLTA2IDE2OjQ4OjE4IiwidXNlclR5cGUiOjIsImNpIjoidjowLHQ6MSxhOnlBUWhvbjhkLGFwOm51bGwiLCJpc3MiOiJ6ZWV3YWluLWRlYnVnIiwiZXhwIjoxNzY3Njg5Mjk4fQ.IlPfUZqDsYIKBQhEYK6AejmPZc0-4UGaf3ljIDpKlU0";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_demo);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.demo), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        rootFrameLayout = findViewById(R.id.demo);
        avatarSDK =  AvatarSDK.getInstance();

        try {
            InitConfig initConfig;
            String jsonString = CommonUtil.readJsonFromExternalCache(this,"config.json");
            if (jsonString == null || jsonString.isEmpty()) {
                initConfig = new InitConfig(token);
            } else {
                Gson gson = new Gson();
                initConfig = gson.fromJson(jsonString, InitConfig.class);
            }

            mUnityPlayer = avatarSDK.init(this, initConfig, new IEngineLifecycleEvents() {
                @Override
                public void onEngineLoaded() {
                    showToast("引擎加载成功！");
                    isEngineReady = true;
                }

                @Override
                public void onEngineUnloaded() {
                }

                @Override
                public void onEngineQuitted() {

                }
            });
            rootFrameLayout.addView(mUnityPlayer);
            avatarSDK.setEngineTranslucent(); //控制是否透明
            mUnityPlayer.requestFocus();
        } catch (Exception e) {
            Log.e(TAG,"avatarSDK init err " + e.getMessage());
        }
        avatarSDK.enableDebug(true);
        setBroadcastCallbacks();
        addDebugBtn();
    }

    private void addDebugBtn() {
        HorizontalScrollView scrollView = new HorizontalScrollView(this);
        scrollView.setHorizontalScrollBarEnabled(true);
        FrameLayout.LayoutParams scrollParams = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        );
        scrollParams.topMargin = 50;
        scrollParams.leftMargin = 20;
        scrollParams.rightMargin = 20;
        scrollView.setLayoutParams(scrollParams);


        LinearLayout linearLayout = new LinearLayout(this);
        ScrollView.LayoutParams linearParams = new ScrollView.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        );
        linearLayout.setLayoutParams(linearParams);
        linearLayout.setOrientation(LinearLayout.HORIZONTAL);
        linearLayout.setBackgroundColor(0x66ccAA00);

        linearLayout.addView(buildDebugBtn("加载数字人", v -> {
            if (isEngineReady) {
                showDHListDialog(dhItems);
            } else {
                showToast("引擎未准备好");
            }
        }));

        linearLayout.addView(buildDebugBtn("卸载数字人", v -> {
            if (!isDigitalHumanReady) {
                showToast("数字人还未加载");
                return;
            }
            avatarSDK.unloadAvatar().thenAccept(reply ->{
                Log.i(TAG,"收到响应：" + reply);
                if (reply.success) {
                    isDigitalHumanReady = false;
                }
                handleCallResp(reply, "卸载数字人");
            }).exceptionally(ex -> {
                Log.e(TAG,"接口处理异常：" + ex.getMessage());
                return null;
            });
        }));

        linearLayout.addView(buildDebugBtn("动作", v -> {
            if (isDigitalHumanReady) {
                showActionListDialog(actionItems);
            } else {
                showToast("数字人还未加载");
            }
        }));

        Button button = new Button(this);
        button.setText("镜头" + AvatarCameraType.WHOLE);
        button.setTag(AvatarCameraType.WHOLE);
        button.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        button.setOnClickListener(v -> {
            if (isDigitalHumanReady) {
                if(AvatarCameraType.WHOLE == button.getTag()) {
                    avatarSDK.setCamera(AvatarCameraType.FACE);
                    button.setText("镜头" + AvatarCameraType.FACE);
                    button.setTag(AvatarCameraType.FACE);
                } else if (AvatarCameraType.FACE == button.getTag()) {
                    avatarSDK.setCamera(AvatarCameraType.HALF);
                    button.setText("镜头" + AvatarCameraType.HALF);
                    button.setTag(AvatarCameraType.HALF);
                } else {
                    avatarSDK.setCamera(AvatarCameraType.WHOLE);
                    button.setText("镜头" + AvatarCameraType.WHOLE);
                    button.setTag(AvatarCameraType.WHOLE);
                }
            } else {
                showToast("数字人还未加载");
            }
        });
        linearLayout.addView(button);


        linearLayout.addView(buildDebugBtn("开始播报", v -> {
            if (!isDigitalHumanReady) {
                showToast("数字人还未加载");
                return;
            }
            showBroadcastSetDialog(actionItems, false);
        }));

        linearLayout.addView(buildDebugBtn("追加播报", v -> {
            if (!isDigitalHumanReady) {
                showToast("数字人还未加载");
                return;
            }
            showBroadcastSetDialog(actionItems, true);
        }));

        linearLayout.addView(buildDebugBtn("暂停播报", v -> {
            if (!isDigitalHumanReady) {
                showToast("数字人还未加载");
                return;
            }
            avatarSDK.pauseBroadcast(true).thenAccept(reply ->
                    Log.i(TAG,"收到响应：" + reply)
            ).exceptionally(ex -> {
                Log.e(TAG,"接口处理异常：" + ex.getMessage());
                return null;
            });
        }));


        linearLayout.addView(buildDebugBtn("恢复播报", v -> {
            if (!isDigitalHumanReady) {
                showToast("数字人还未加载");
                return;
            }
            avatarSDK.resumeBroadcast().thenAccept(reply ->
                    Log.i(TAG,"收到响应：" + reply)
            ).exceptionally(ex -> {
                Log.e(TAG,"接口处理异常：" + ex.getMessage());
                return null;
            });
        }));

        linearLayout.addView(buildDebugBtn("结束播报", v -> {
            if (!isDigitalHumanReady) {
                showToast("数字人还未加载");
                return;
            }
            avatarSDK.resumeBroadcast().thenAccept(reply ->
                    Log.i(TAG,"收到响应：" + reply)
            ).exceptionally(ex -> {
                Log.e(TAG,"接口处理异常：" + ex.getMessage());
                return null;
            });
        }));

        scrollView.addView(linearLayout);
        rootFrameLayout.addView(scrollView);
    }

    public Button buildDebugBtn(String text, View.OnClickListener onClickListener) {
        Button button = new Button(this);
        button.setText(text);
        button.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        button.setOnClickListener(onClickListener);
        return button;
    }

    public void initializeAvatar(String avatarCode) {
        currentAvatarCode = avatarCode;
        avatarSDK.initializeAvatar(avatarCode, AvatarCameraType.WHOLE).thenAccept(reply -> {
            Log.i(TAG,"收到响应：" + reply);
            isDigitalHumanReady = reply.success;
            handleCallResp(reply, "加载数字人");
        }).exceptionally(ex -> {
            Log.e(TAG,"接口处理异常：" + ex.getMessage());
            showToast(ex.getMessage());
            return null;
        });
    }

    public void playMotion(String clipCode) {
        avatarSDK.playMotion(clipCode).thenAccept(reply ->
                handleCallResp(reply, "播放动作")
        ).exceptionally(ex -> {
            Log.i(TAG,"接口处理异常：" + ex.getMessage());
            return null;
        });
    }

    private void showDHListDialog(List<String> items) {
        ListWithEditTextDialog dialog = new ListWithEditTextDialog(
                this,
                "选择数字人",
                "请输入编码",
                items,
                new ListWithEditTextDialog.OnConfirmListener() {
                    @Override
                    public void onConfirm(String inputText) {

                    }

                    @Override
                    public void onItemSelected(int position, String text) {
                        initializeAvatar(text);
                    }
                }
        );
        dialog.show();
    }

    private void showActionListDialog(List<String> items) {
        ListWithEditTextDialog dialog = new ListWithEditTextDialog(
                this,
                "选择动作",
                "请输入编码",
                items,
                new ListWithEditTextDialog.OnConfirmListener() {
                    @Override
                    public void onConfirm(String inputText) {

                    }

                    @Override
                    public void onItemSelected(int position, String text) {
                        playMotion(text);
                    }
                }
        );
        dialog.show();
    }

    private void showBroadcastSetDialog(List<String> items, boolean isAppend) {
        BroadcastSettingsDialog dialog = new BroadcastSettingsDialog(
                this,
                "播报参数设置",
                currentAvatarCode,
                items,
                broadcastParams -> {
                    avatarSDK.startBroadcast(broadcastParams, isAppend);
                }
        );
        dialog.show();
    }

    private void handleCallResp(SDKResponse response, String msg) {
        if (response.success) {
            showToast("成功" + msg);
        } else {
            showToast(response.message);
        }
    }

    private void showToast(String msg) {
        runOnUiThread(() -> {
            Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
        });
    }

    private void setBroadcastCallbacks() {
        avatarSDK.setBroadcastCallbacks(new IBroadcastCallbacks() {
            @Override
            public void onStart() {
                showToast("播报开始了");
            }

            @Override
            public void onFinish() {
                showToast("阶段-播报完成");
            }

            @Override
            public void onError(SDKException sdkException) {
                showToast("播报异常 " + sdkException.getMessage());
            }

            @Override
            public void onPause() {
                showToast("播报暂停了");
            }

            @Override
            public void onResume() {
                showToast("播报恢复了");
            }

            @Override
            public void onStop() {
                showToast("播报结束了");
            }

            @Override
            public void onAbort() {
                showToast("播报中止了");
            }
        });
    }


    //--以下关联引擎生命周期相关
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        avatarSDK.onNewIntent(intent);
    }

    @Override
    protected void onDestroy () {
        avatarSDK.onDestroy();
        super.onDestroy();
    }

    @Override
    protected void onStop() {
        super.onStop();
        avatarSDK.onStop();
    }

    @Override
    protected void onStart() {
        super.onStart();
        avatarSDK.onStart();
    }

    @Override
    protected void onPause() {
        super.onPause();
        avatarSDK.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        avatarSDK.onResume();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        avatarSDK.onLowMemory();
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        avatarSDK.onTrimMemory(level);
    }

    // This ensures the layout will be correct.
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        avatarSDK.onConfigurationChanged(newConfig);
    }

    // Notify Unity of the focus change.
    @Override public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        avatarSDK.onWindowFocusChanged(hasFocus);
    }

    // For some reason the multiple keyevent type is not supported by the ndk.
    // Force event injection by overriding dispatchKeyEvent().
    @Override public boolean dispatchKeyEvent(KeyEvent event) {
        if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
            finish();;
        }

        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return avatarSDK.dispatchKeyEvent(event);
        return super.dispatchKeyEvent(event);
    }

    // Pass any events not handled by (unfocused) views straight to UnityPlayer
    @Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return avatarSDK.onKeyUp(keyCode, event); }
    @Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return avatarSDK.onKeyDown(keyCode, event); }
    @Override public boolean onTouchEvent(MotionEvent event)          { return avatarSDK.onTouchEvent(event); }
    /*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return avatarSDK.onGenericMotionEvent(event); }
}